package com.hmtech.ayp.common.s3.service;


import com.amazonaws.HttpMethod;
import com.hmtech.ayp.common.s3.domain.AwsTempCredentials;
import com.hmtech.ayp.common.s3.domain.S3UploadResult;
import com.hmtech.ayp.common.s3.exception.S3Exception;

import java.util.List;

/**
 * S3服务
 *
 * @author 闫家洪（yanjiahong@vcredit.com）
 * @since 2023/12/18
 */
public interface IS3Service {
    /**
     * 上传本地文件到S3
     *
     * @param filename 上传到S3的文件名，最后S3的完整key就是bucketName + "/" + filename
     * @param data     需要被上传到S3的文件数据
     */
    S3UploadResult upload(String filename, byte[] data) throws S3Exception;

    /**
     * 上传本地文件到S3
     *
     * @param localFilepath 需要被上传的本地文件路径
     */
    S3UploadResult upload(String localFilepath) throws S3Exception;

    /**
     * 将文件下载到个本地路径
     *
     * @param s3path     上传到S3的文件名，最后S3的完整key就是bucketName + "/" + filename
     * @param dstDirPath 下载到本地的目录的路径
     */
    void download(String s3path, String dstDirPath) throws S3Exception;

    /**
     * 将S3对象下载下来，并转换为字节数组
     * <p>！！！大文件不要用这个！！！</p>
     *
     * @param s3path 上传到S3的文件名，最后S3的完整key就是bucketName + "/" + filename
     */
    byte[] download(String s3path) throws S3Exception;

    /**
     * 并发上传本地文件到S3。
     * <p>如果文件大于大小阈值，将会进行分片上传</p>
     *
     * @param localFilepath 本地文件路径
     * @return 文件上传结果
     */
    S3UploadResult syncUploadConcurrently(String localFilepath) throws S3Exception;

    /**
     * 并发上传本地文件到S3。
     * <p>如果文件大于大小阈值，将会进行分片上传</p>
     *
     * @param localFilepath 本地文件路径列表
     * @return 文件上传结果
     */
    List<S3UploadResult> syncUploadConcurrently(List<String> localFilepath) throws S3Exception;

    /**
     * 生成预签名的URL
     *
     * @param s3path           上传到S3的文件名，最后S3的完整路径就是bucketName + "/" + filename
     * @param method           HTTP的方法，目前支持GET和PUT，GET表示要将数据下载到本地，PUT表示要将数据上传到S3
     * @param expiresInSeconds 签名过期时间，单位秒
     * @return 预签名的URL
     */
    String genPreSignedUrl(String s3path, HttpMethod method, long expiresInSeconds) throws S3Exception;


    /**
     * 生成预签名的URL，使用系统配置的默认过期时间
     *
     * @param s3path 上传到S3的文件名，最后S3的完整路径就是bucketName + "/" + filename
     * @param method HTTP的方法，目前支持GET和PUT，GET表示要将数据下载到本地，PUT表示要将数据上传到S3
     * @return 预签名的URL
     */
    String genPreSignedUrl(String s3path, HttpMethod method) throws S3Exception;

    /**
     * 生成预签名的URL，用于下载文件
     *
     * @param s3path 上传到S3的文件名，最后S3的完整路径就是bucketName + "/" + filename
     * @return 预签名的URL
     */
    String genPreSignedUrlForPut(String s3path) throws S3Exception;

    /**
     * 生成预签名的URL，用于上传文件，过期时间默认为5分钟
     *
     * @param s3path 上传到S3的包含bucketName的路径，最后S3的完整路径就是bucketName + "/" + key
     * @return 预签名的URL
     */
    String genPreSignedUrlForGet(String s3path) throws S3Exception;

    /**
     * 获取临时上传凭证
     *
     * @return 临时上传凭证
     */
    AwsTempCredentials getTempCredentialsForPutObject() throws S3Exception;
}
